﻿using System;

namespace Levfier.Proccessors.Parameters
{
    /// <summary>
    /// 現在値が変更された時のイベントハンドラ
    /// </summary>
    /// <param name="sender">イベント発生元</param>
    public delegate void CurrentValueChanged(object sender);

    public enum ParameterType : int
    {
        //値
        Value = 0,

        //On Off
        Bool = 1
    }

    /// <summary>
    /// パラメータ
    /// </summary>
    [Serializable]
    public class ProccessParameter
    {
        /// <summary>
        /// 値が変更された時のイベントハンドラ
        /// </summary>
        public event CurrentValueChanged ValueChanged;

        /// <summary>
        /// IDの連番
        /// </summary>
        private static int totalId = 0;

        /// <summary>
        /// ID
        /// </summary>
        public string Id
        {
            get { return id; }
            set { this.id = value; }
        }

        /// <summary>
        /// ID
        /// </summary>
        private string id;

        /// <summary>
        /// パラメータ名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// パラメータのタイプ
        /// </summary>
        public ParameterType Type { get; set; }

        /// <summary>
        /// 現在の値
        /// </summary>
        public double Value {
            get
            {
                return this.value;
            }
            set
            {
                if(value > this.MaxValue)
                {
                    this.value = this.MaxValue;
                }
                else if(value < this.MinValue)
                {
                    this.value = this.MinValue;
                }
                this.value = value;

                //イベント発生
                if (null != this.ValueChanged)
                {
                    this.ValueChanged(this);
                }
            }
        }

        /// <summary>
        /// 設定できる値の最大値
        /// </summary>
        public double MaxValue { get; set; }

        /// <summary>
        /// 設定できる値の最小値
        /// </summary>
        public double MinValue { get; set; }

        /// <summary>
        /// パラメータを使用されているか否か
        /// </summary>
        public bool IsUsed { get; set; }

        /// <summary>
        /// パラメータの移動刻み
        /// </summary>
        public double Step { get; set; }

        /// <summary>
        /// 現在の値
        /// </summary>
        private double value;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public ProccessParameter()
        {
            this.IsUsed = false;
            //デフォルト設定
            this.Type = ParameterType.Value;

            this.id = "P" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + totalId;
            totalId++;
        }

        /// <summary>
        /// 入力値をデシベル値に変換する
        /// </summary>
        /// <param name="value">入力値</param>
        /// <returns>デシベル値</returns>
        static public double ConvertValueToDB(double value)
        {
            return 20 * Math.Log(value, 10.0d);
        }

        /// <summary>
        /// デシベル値を変換する
        /// </summary>
        /// <param name="db">デシベル値</param>
        /// <returns>通常の値</returns>
        static public double ConvertDBToValue(double db)
        {
            return Math.Pow(10.0, db / 20.0d);
        }
    }
}
